﻿using MongoDB.Bson;
using MongoDB.Driver;
using SpreadsheetGear;
using Sustainalytics.AwsS3.Client;
using Sustainalytics.ClientDW.DataAccessLayer;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.ClientDW.Entities.Universes;
using Sustainalytics.DataLayer;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities;
using Sustainalytics.Entities.ConnectionStrings;
using Sustainalytics.Entities.ProductInvolvement;
using Sustainalytics.Entities.SustainableProducts;
using Sustainalytics.MongoDB.Extensions;
using Sustainalytics.Portfolios.BL;
using Sustainalytics.ScreeningTool.BL;
using Sustainalytics.ScreeningTool.BL.Model;
using Sustainalytics.Utils;
using Sustainalytics.Utils.Configuration;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IMongoDatabaseExtensions = Sustainalytics.DataLayer.IMongoDatabaseExtensions;

namespace Sustainalytics.PregenerateScreeningReports.Service
{
    // load maximal file
    // load distribution data     
    // clone files 
    public class OneReportWorkerProcess
    {
        Dictionary<ConnectionStringType, string> _cnxs;
        IEnumerable<Guid> _requestIds;
        string _tempPath;
        string _fileName;
        string _clientDWMaster;
        IPregeneratedReportManager _pregeneratedReportManager;
        ICompanyScreeningRepository _companyScreeningRepository;
        string _accountPosition;
        string _clientPlatform;



        static public OneReportWorkerProcess NewInstanceFromConfig(string[] args)
        {
            var guids = args[1].Split('|').Select(x => Guid.Parse(x)).ToArray();
            var tempPath = SettingsHelper.Read<string>("TempPath", System.IO.Path.GetTempPath());
            var cnx1 = System.Configuration.ConfigurationManager.ConnectionStrings["ClientDWMaster"].ConnectionString;
            var cnx2 = System.Configuration.ConfigurationManager.ConnectionStrings["ClientPlatform"].ConnectionString;

            var accountPosition = SettingsHelper.Read<string>("AccountNameCellPosition", "D6");
            return new OneReportWorkerProcess(args[0], tempPath, guids, cnx1, cnx2, accountPosition);
        }

        public OneReportWorkerProcess(string fileName, string tempPath, IEnumerable<Guid> requestsIds,
                                string clientDWMaster, string clientPlatform, string accountPosition)
        {
            PSREventSource.Log.WorkerProcess(Process.GetCurrentProcess().Id, fileName, tempPath,
                        string.Join<Guid>(",", requestsIds), clientDWMaster, clientPlatform, accountPosition);
            _clientDWMaster = clientDWMaster;
            _fileName = Path.Combine(tempPath, fileName);
            _requestIds = requestsIds;
            _tempPath = tempPath;
            _accountPosition = accountPosition;
            _clientPlatform = clientPlatform;

            if (!File.Exists(_fileName))
                throw new PSR_FileNotFound(_fileName);

        }


        private ExportScreening CreatExportScreening(ScreeningToolReportDistributionSession session)
        {
            var connectionStringsMap = session.ConnectionStrings;
            var screeningDataRepository = ScreeningDataRepository.GetScreeningDataRepository(connectionStringsMap[ConnectionStringType.ScreeningDW]);

            var portfolioManager = new PortfolioReadHandler(
                new PortfolioTypeCollection<Portfolio>(new RepositoryCollection<Portfolio>(connectionStringsMap[ConnectionStringType.ClientPlatform]), new RepositoryCollection<Portfolio>(connectionStringsMap[ConnectionStringType.ClientPlatform])),
                new PortfolioTypeCollection<PortfolioDetails>(new RepositoryCollection<PortfolioDetails>(connectionStringsMap[ConnectionStringType.ClientPlatform]), new RepositoryCollection<PortfolioDetails>(connectionStringsMap[ConnectionStringType.ClientPlatform])),
                new RepositoryCollection<CorporateDataBasic>(connectionStringsMap[ConnectionStringType.ClientDW], "CorporateData"));


            _companyScreeningRepository = CompanyScreeningRepository.GetCompanyScreeningRepository(
                connectionStringsMap[ConnectionStringType.ClientPlatform]);
            var exportBL = new ExportScreeningEx(CompanyScreeningRepository.GetCompanyScreeningRepository(connectionStringsMap[ConnectionStringType.ClientPlatform]),
                                                ClientDwRepository.GetInstance(connectionStringsMap[ConnectionStringType.ClientDW]),
                                                portfolioManager,
                                                UniversesRepository.GetUniversesRepository(connectionStringsMap[ConnectionStringType.ClientUniverses]),
                                                new FilterCriteriaRepository(connectionStringsMap[ConnectionStringType.ClientPlatform]),
                                                new RepositoryCollection<CorporateData>(connectionStringsMap[ConnectionStringType.ClientDW]),
                                                screeningDataRepository,
                MongoFactory.GetCollectionFromDatabase<CorporateData>(MongoFactory.GetConnectionStrings().ClientDW),
                MongoFactory.GetCollectionFromDatabase<SustainableProductsFramework>(MongoFactory.GetConnectionStrings().ProductInvolvementDW),
                MongoFactory.GetCollectionFromDatabase<ProductInvolvementFramework>(MongoFactory.GetConnectionStrings().ProductInvolvementDW));
            return exportBL;
        }

        public void Run()
        {
            var cron = new Cronometer();
            // start loading files
            var loader = Task<MaximalReportInternal>.Run(() => new MaximalReportInternal(_fileName, _clientPlatform));

            //load data  sessions = 
            var sessionId = MaximalReportHelper.SessionIdFromMaximalReportName(_fileName);
            var sessionColl = IMongoDatabaseExtensions.GetCollection<ScreeningToolReportDistributionSession>(DataLayer.MongoDatabaseFactory.GetDatabase(_clientDWMaster));

            var session = sessionColl.AsQueryable().First(x => x.Id == sessionId);
            _cnxs = session.ConnectionStrings;

            var accountsColl = IMongoDatabaseExtensions.GetCollection<Account>(DataLayer.MongoDatabaseFactory.GetDatabase(_clientPlatform));

            // load data - requests           
            var requestsColl = IMongoDatabaseExtensions.GetCollection<ScreeningToolReportRequest>(DataLayer.MongoDatabaseFactory.GetDatabase(_clientDWMaster));
            var requests = requestsColl.Find(e => _requestIds.Contains(e.Id))
                                         .As<ScreeningToolReportRequest>()
                                         .ToList()
                                         .OrderBy<ScreeningToolReportRequest, int>(x => x.CompaniesIds.Count());

            var corpDataColl = IMongoDatabaseExtensions.GetCollection<CorporateData>(DataLayer.MongoDatabaseFactory.GetDatabase(_cnxs[ConnectionStringType.ClientDW]));
            var companyIdCapitalIQDic = corpDataColl.Find(new BsonDocument())
                                                 .Project(Builders<CorporateData>.Projection.Include(x => x.Id).Include(x => x.CapitalIqId))
                                                 .As<CorporateData>()
                                                 .ToList()
                                                 .ToDictionary(x => x.Id, x => x.CapitalIqId.ToString());
            var companyUniverse =
                corpDataColl.Find(new BsonDocument())
                    .Project(Builders<CorporateData>.Projection.Include(a => a.Id).Include(a => a.UniverseIds))
                    .As<CorporateData>()
                    .ToList()
                    .ToDictionary(a => a.Id, a => a.UniverseIds);



            _pregeneratedReportManager = NewPregeneratedReportManagerFromConfig(_cnxs);
            if (_pregeneratedReportManager == null)
                throw new ApplicationException("_pregeneratedReportManager is null");

            var export = CreatExportScreening(session);
            var maximalExcel = loader.Result;
            cron.Mark("loading complete");

            var filter = MongoFactory.GetCollectionFromClientPlatform<Filter>()
                                    .Find(x => x.Id == maximalExcel.ReportId)
                                    .FirstOrDefault();
            var universecoll = MongoFactory.GetCollectionFromDatabase<Universe>(_cnxs[ConnectionStringType.ClientUniverses]);
            var universeNameFromFilter = string.Empty;
            var filterHasUniverse = filter.UniverseId.HasValue;
            if (filter.UniverseId.HasValue)
            {
                universeNameFromFilter = universecoll.Find(x => x.Id == filter.UniverseId.Value)
                                                            .Project(x => x.Name)
                                                            .FirstOrDefault();
            }


            foreach (var r in requests)
            {
                try
                {
                    Debug.WriteLine("Processing Requests:{0}", r.Id);
                    foreach (var accountId in r.AccountIds)
                    {
                        try
                        {
                            var companiesInFilterUniverse = new List<Guid>();
                            if (filterHasUniverse)
                            {
                                var universeId = universecoll.Find(x => x.Name == universeNameFromFilter && accountId == x.AccountId)
                                                                .Project(x => x.Id)
                                                                .FirstOrDefault();
                                companiesInFilterUniverse = MongoFactory.GetCollectionFromDatabase<UniverseCompany>(_cnxs[ConnectionStringType.ClientUniverses])
                                                                .Find(x => x.AccountId == accountId && x.UniverseId == universeId)
                                                                .Project(x => x.CompanyId)
                                                                .ToList()
                                                                .Distinct()
                                                                .ToList();
                            }


                            var accountName = accountsColl.AsQueryable()
                               .Where(x => x.Id == accountId)
                               .Select(x => x.Name).FirstOrDefault();
                            var log = ProcesOneExcelPerAccount(accountId, export, maximalExcel, companyUniverse, r, companyIdCapitalIQDic,
                                                                             _accountPosition, accountName, companiesInFilterUniverse);
                            Debug.WriteLine(log);

                            PSREventSource.Log.ReportStatus(Process.GetCurrentProcess().Id, log);
                        }
                        catch (Exception ex)
                        {
                            PSREventSource.Log.Exception(ex);
                        }

                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                    PSREventSource.Log.Exception(ex);
                }
                finally
                {
                    cron.Mark("completed: " + maximalExcel.Name);
                }
            }

            PSREventSource.Log.WorkerProcessCompleted(Process.GetCurrentProcess().Id, cron.ToString());
        }

        public PregeneratedReportManager NewPregeneratedReportManagerFromConfig(Dictionary<ConnectionStringType, string> dictionary)
        {
            var screeningDWcnx = dictionary[ConnectionStringType.ScreeningDW];
            var repoPregenerated = new RepositoryCollection<PregeneratedReport>(screeningDWcnx);
            var s3Client = new S3Client(new S3ClientSettings()
            {
                AccessKey = SettingsHelper.Read("accesKeyId", "AKIAJKGZZMOFAVOVLHJA"),
                SecretAccessKey = SettingsHelper.Read("awsSecretKey", "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"),
                ServiceEndPoint = SettingsHelper.Read("s3ServiceEndPoint", "https://s3-eu-west-1.amazonaws.com/")
            });
            var lastLetter = screeningDWcnx.Contains("ScreeningDW_A") ? "_A" : screeningDWcnx.Contains("ScreeningDW_B") ? "_B" : "";
            var s3Folder = SettingsHelper.Read("s3FolderPregen", "PregeneratedReports") + lastLetter;
            var repoFilter = new RepositoryCollection<Filter>(dictionary[ConnectionStringType.ClientPlatform]);
            PSREventSource.Log.S3Folder(s3Folder);
            return new PregeneratedReportManager(s3Client, repoPregenerated, repoFilter, s3Folder);
        }



        private string ProcesOneExcelPerAccount(Guid accountId,
                                                    ExportScreening export,
                                                    MaximalReportInternal maximalExcel,
                                                    Dictionary<Guid, List<int>> companyUniverse,
                                                    ScreeningToolReportRequest r,
                                                    Dictionary<Guid, string> companyIdCapitalIQDic,
                                                    string accountPosition,
                                                    string accountName,
                                                    List<Guid> companiesInFiltersUniverse)
        {
            var helper = new CUSIPISINClaimsCheckerBL();
            var sb = new StringBuilder();
            sb.AppendFormat("Processing account/request:{0}|{1}", accountId, r.Id);
            sb.AppendLine();

            var claimsPrincipal = (new ClaimsReaderForISINCUSIPClaims(ConfigurationManager.AppSettings["RedisServer"], Convert.ToInt32(ConfigurationManager.AppSettings["DistributionDataSet"])))
                .CollectAccountClaimsForISINAndCUSIP(String.Format("{0}#@%{1}", accountName, accountId));

            var screeningDataRepository = ScreeningDataRepository.GetScreeningDataRepository(_cnxs[ConnectionStringType.ScreeningDW]);
            var universeRepository = UniversesRepository.GetUniversesRepository(_cnxs[ConnectionStringType.ClientUniverses]);

            var filterDetails = _companyScreeningRepository.GetFilterByFilterId(maximalExcel.ReportId);
            var filterCriterias = _companyScreeningRepository.GetFilterCriteriasByFilterId(maximalExcel.ReportId);

            var accountUniverses = universeRepository.GetUniversesByAccountId(filterDetails.AccountId);

            var portfolioData = GetPortfolioDataFromFilter(filterDetails, accountUniverses);

            var portfolioManager = new PortfolioReadHandler(
                 new PortfolioTypeCollection<Portfolio>(new RepositoryCollection<Portfolio>(_cnxs[ConnectionStringType.ClientPlatform]), 
                 new RepositoryCollection<Portfolio>(_cnxs[ConnectionStringType.ClientDW])),
                 new PortfolioTypeCollection<PortfolioDetails>(
                     new RepositoryCollection<PortfolioDetails>(_cnxs[ConnectionStringType.ClientPlatform]), 
                     new RepositoryCollection<PortfolioDetails>(_cnxs[ConnectionStringType.ClientDW])),
                 new RepositoryCollection<CorporateDataBasic>(_cnxs[ConnectionStringType.ClientDW], "CorporateData"));

            List<Guid> companiesById = null;
            if (filterDetails.PortfolioId != null)
                companiesById = portfolioManager.GetCompanyIdsByPortfolio(filterDetails.PortfolioId.Value).ToList();

            helper.checkIsinCusipClaims(claimsPrincipal);

            ScreeningReportData screeningReportData = new ScreeningReportData
            {
                CompanyData = screeningDataRepository.GetCompaniesData(filterDetails, accountUniverses.Select(p => p.Id).ToList(), accountUniverses, portfolioData,
                        filterCriterias, companiesById, helper.HasISINClaim, helper.HasCUSIPClaim)
            };

            if (accountName != null) screeningReportData.ClientName = accountName;

            screeningReportData.PortfolioName = filterDetails.PortfolioName;
            screeningReportData.FilterName = filterDetails.Name;
            screeningReportData.FilterSettings = filterDetails;

            var noaccesTuple = export.GetNoAccesDataForPregeneration(
                maximalExcel.ReportId,
                accountId,
                companyUniverse,
                helper.HasISINClaim,
                helper.HasCUSIPClaim);
            var noacces = noaccesTuple.Item2;
            var totalCriteriaColums = noaccesTuple.Item1;
            sb.AppendLine("Got no acces data");

            var ir = new InternalRequest(r, companyIdCapitalIQDic, maximalExcel.PositionsInMaximalReport, companiesInFiltersUniverse);
            sb.AppendLine("Create new workbook");


            var noAccessData = InternalRequest.ConvertForNoAcces(noacces, companyIdCapitalIQDic, maximalExcel.PositionsInMaximalReport);

            var workbook = CreateWorkBook(maximalExcel.Workbook, ir.PositionsInMaximalReport.Keys, noAccessData, totalCriteriaColums,
                                        accountPosition, accountName, maximalExcel.IsFilterNotReport);
            sb.AppendLine("Create workbook done");

            var fileName = string.Format("R_{0}_{1}_{2}.xlsx", r.Id, maximalExcel.ReportId, accountId);
            var savepath = Path.Combine(_tempPath, fileName);

            var pregen = new PregeneratedReport()
            {
                Id = Guid.NewGuid(),
                AccountId = accountId,
                FilterId = maximalExcel.ReportId,
                ReportName = string.Format("{0}_{1}", maximalExcel.ReportId, accountId),
                Content = workbook.SaveToMemory(FileFormat.OpenXMLWorkbook)
            };
            _pregeneratedReportManager.PersistFileS3(pregen);


            workbook.SaveAs(savepath, FileFormat.OpenXMLWorkbook);
            workbook.Close();
            sb.AppendLine("Saved closed: " + savepath);
            workbook = null;
            noacces = null;
            return sb.ToString();
        }

        protected List<PortfolioDetails> GetPortfolioDataFromFilter(Filter filterDetails, List<Universe> accountUniverseIds)
        {
            List<PortfolioDetails> portfolioData = null;

            var portfolioManager = new PortfolioReadHandler(
                 new PortfolioTypeCollection<Portfolio>(new RepositoryCollection<Portfolio>(_cnxs[ConnectionStringType.ClientPlatform]), new RepositoryCollection<Portfolio>(_cnxs[ConnectionStringType.ClientDW]))
                , new PortfolioTypeCollection<PortfolioDetails>(new RepositoryCollection<PortfolioDetails>(_cnxs[ConnectionStringType.ClientPlatform]), new RepositoryCollection<PortfolioDetails>(_cnxs[ConnectionStringType.ClientDW]))
                , new RepositoryCollection<CorporateDataBasic>(_cnxs[ConnectionStringType.ClientDW], "CorporateData"));

            var portfolioId = filterDetails.PortfolioId.GetValueOrDefault();
            var universes = accountUniverseIds.Select(a => a.Id).ToList();
            if (portfolioId != Guid.Empty && universes.Any())
            {
                var securities = portfolioManager.GetPortfolioSecurities(portfolioId, universes);
                portfolioData = securities.Select(x => x.GetPortfolioDetails()).ToList();
            }

            return portfolioData;
        }

        private static IWorkbook CreateWorkBook(IWorkbook main, IList<int> positions, SortedList<int, List<int>> noAccessDictionary,
                                                int totalCriteriaColums, string accountPositionForName, string accountName,
                                                bool isFilterNotReport)
        {
            // clone data 
            var workbook = Factory.GetWorkbook();
            IRange cellsSource;
            IRange cellsDestination;
            PrepareSheets(main, workbook, out cellsSource, out cellsDestination);

            // prepare a full line of no access, handy for large files
            var fullLineNoAccess = PrepareFullNoAccess(totalCriteriaColums, main);

            // copy and set sheets 
            var idx = 1;
            foreach (var pos in positions)
            {
                cellsSource[pos, 0].EntireRow.Copy(cellsDestination[idx, 0], PasteType.All, PasteOperation.None, false, false);
                if (noAccessDictionary.ContainsKey(pos))
                {
                    var columnsIndexList = noAccessDictionary[pos];
                    if (isFilterNotReport && columnsIndexList.Count() == totalCriteriaColums)
                    {
                        cellsDestination[idx, 4].Value = "N/A";
                        cellsDestination[idx, 4].Font.Color = Color.FromArgb(0, 0, 0);
                    }

                    if (columnsIndexList.Count() == totalCriteriaColums)
                    {
                        fullLineNoAccess.Copy(cellsDestination[idx, isFilterNotReport ? 5 : 4], PasteType.All, PasteOperation.None, false, false);
                    }
                    else
                    {
                        foreach (var v in columnsIndexList)
                        {
                            cellsDestination[idx, v - 1].Value = "No Access";
                            cellsDestination[idx, v - 1].Font.Color = Color.FromArgb(0, 0, 0);
                        }
                    }
                }
                idx++;
            }

            workbook.Worksheets[0].Cells[accountPositionForName].Value = accountName;
            Add3SheetIfAny(main, workbook);
            workbook.Worksheets[0].Select();
            return workbook;
        }

        private static IRange PrepareFullNoAccess(int totalCriteriaColums, IWorkbook workbook)
        {
            var noAccessLine = workbook.Worksheets[0].Cells;
            for (var i = 0; i < totalCriteriaColums; i++)
            {
                noAccessLine[100, i].Value = "No Access";
                noAccessLine[100, i].Font.Color = Color.FromArgb(0, 0, 0);
            }
            var fullLineNoAccess = noAccessLine[100, 0, 100, totalCriteriaColums];
            return fullLineNoAccess;
        }

        private static void PrepareSheets(IWorkbook main, IWorkbook workbook, out IRange cellsSource, out IRange cellsDestination)
        {
            main.Worksheets[0].CopyAfter(workbook.Worksheets[0]);
            main.Worksheets[1].CopyAfter(workbook.Worksheets[1]);
            workbook.Worksheets[0].Delete();

            workbook.Worksheets[0].Name = main.Worksheets[0].Name;
            workbook.Worksheets[1].Name = main.Worksheets[1].Name;

            var rows = main.Worksheets[1].UsedRange.RowCount;
            var columns = main.Worksheets[1].UsedRange.ColumnCount;

            workbook.Worksheets[1].UsedRange[1, 0, rows, columns].EntireRow.Delete();

            cellsSource = main.Worksheets[1].Cells;
            cellsDestination = workbook.Worksheets[1].Cells;
        }

        private static void Add3SheetIfAny(IWorkbook main, IWorkbook workbook)
        {
            // add filter settings if exists
            if (main.Worksheets.Count >= 3)
            {
                var filterSettingsSheet = main.Worksheets[2];
                if (filterSettingsSheet != null)
                {
                    filterSettingsSheet.CopyAfter(workbook.Worksheets[1]);
                    workbook.Worksheets[2].Name = filterSettingsSheet.Name;

                }
            }
        }

        class MaximalReportInternal
        {
            public MaximalReportInternal(string name, string connectionString)
            {
                Name = name;
                ReportId = MaximalReportHelper.ReportIdFromMaximalReportName(name);
                Workbook = Factory.GetWorkbookSet().Workbooks.Open(name);

                var range = Workbook.Worksheets[1].UsedRange;
                var count = range.RowCount;
                PositionsInMaximalReport = new Dictionary<string, int>(count);
                for (int pos = 1; pos < count; pos++)
                    PositionsInMaximalReport.Add(Convert.ToString((double)range[pos, 1].Value), pos);

                var targetType = MongoFactory.GetCollectionFromClientPlatform<Filter>()
                                        .Find(x => x.Id == ReportId)
                                        .Project(x => x.TargetType)
                                        .FirstOrDefault();

                IsFilterNotReport = (targetType == TargetType.Screening);

            }
            public Guid ReportId { get; private set; }
            public string Name { get; private set; }
            public IWorkbook Workbook { get; private set; }
            public bool IsFilterNotReport { get; private set; }
            public Dictionary<string, int> PositionsInMaximalReport { get; private set; }
        }
        class InternalRequest
        {
            public InternalRequest(ScreeningToolReportRequest request,
                                    Dictionary<Guid, string> companyId2CIQID,
                                    Dictionary<string, int> positionsInMaximalReport,
                                    List<Guid> companiesInFiltersUniverse)
            {
                Request = request;

                var companiesIds = request.CompaniesIds;
                if (companiesInFiltersUniverse.Any())
                    companiesIds = request.CompaniesIds.Intersect(companiesInFiltersUniverse);

                PositionsInMaximalReport = Convert(companiesIds, companyId2CIQID, positionsInMaximalReport);
            }

            public ScreeningToolReportRequest Request { get; set; }

            public SortedList<int, string> PositionsInMaximalReport { get; set; }

            public static SortedList<int, string> Convert(IEnumerable<Guid> companies,
                                                            Dictionary<Guid, string> companyId2CIQID,
                                                            Dictionary<string, int> positionsInMaximalReport)
            {
                var result = new SortedList<int, string>();
                foreach (var c in companies)
                {
                    if (companyId2CIQID.ContainsKey(c))
                    {
                        var ciqid = companyId2CIQID[c];
                        if (!positionsInMaximalReport.ContainsKey(ciqid))
                            continue;
                        var pos = positionsInMaximalReport[ciqid];
                        result[pos] = ciqid;
                    }
                    else
                    {
                        PSREventSource.Log.CompanyNotFoundInCIQIDDictionary(Process.GetCurrentProcess().Id, c.ToString());
                    }
                }
                return result;
            }

            public static SortedList<int, List<int>> ConvertForNoAcces(Dictionary<Guid, List<int>> companies,
                                                            Dictionary<Guid, string> companyId2CIQID,
                                                            Dictionary<string, int> positionsInMaximalReport)
            {
                var result = new SortedList<int, List<int>>();
                foreach (var c in companies)
                {
                    var ciqid = companyId2CIQID[c.Key];
                    if (!positionsInMaximalReport.ContainsKey(ciqid))
                        continue;

                    var pos = positionsInMaximalReport[ciqid];
                    result[pos] = c.Value;
                }
                return result;
            }
        }
    }
}



